import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.*;


public class SelectionFrame extends JFrame {

	private static final long serialVersionUID = 1L;
	private JSlider delaySlider, speedSlider, pickupSlider, shootSlider;
	private final int sliderMin = 0, sliderMax = 100, maxSum = 250;
	private int tempDelay = 50, tempSpeed = 50, tempPickup = 50, tempShoot = 50, currentSum, redValue, greenValue, blueValue;
	private JTextArea timeDisplay = new JTextArea();
	private String remainingPoints, message;
	private JButton confirmSelection;
	private Color color = new Color(255, 255, 255);
	private JPanel bottom = new JPanel(), sliders = new JPanel();
	public static final Random random = new Random();
	private HelpFrame help;
	private GraphicsEnvironment e1;
	private JPanel fields, rebound, logomotion, robot;
	private JLabel reboundLabel, logomotionLabel, robotLabel;
	private ImageIcon robotIcon = new ImageIcon("ExpandedUserRobot.png");
	private ImageIcon logomotionIcon  = new ImageIcon("Logomotion.png");
	private ImageIcon reboundIcon = new ImageIcon("ReboundRumble.png");
	private ImageIcon selectedReboundIcon = new ImageIcon("SelectedReboundRumble.png");
	private ImageIcon selectedLogomotionIcon = new ImageIcon("SelectedLogomotion.png");
	private JLabel yourRobotLabel, sliderInstructions, selectFieldLabel;
	private JButton logomotionButton, reboundButton;
	private JPanel userRobotPanel, selectAttributesPanel, pointsLeftPanel, selectFieldPanel, startMatchPanel;
	private JPanel keyInstructionPanel;
	private JTextArea keyInstructions;

	private Color backgroundColor = new Color(88, 140, 180);
	private Font largeLabelFont = new Font("Cambria", Font.BOLD, 40);

	public SelectionFrame() {

		//key instruction panel
		keyInstructionPanel = new JPanel();
		keyInstructions = new JTextArea("Press H for help,\nQ to quit");
		keyInstructions.setFont(new Font("Cambria", Font.ITALIC, 20));
		keyInstructionPanel.setBackground(Color.white);
		keyInstructionPanel.setBorder(BorderFactory.createLineBorder(Color.black));
		keyInstructionPanel.add(keyInstructions);

		//buttons to select field
		fields = new JPanel();
		fields.setBackground(Color.LIGHT_GRAY);
		fields.setLayout(new GridLayout(1,2));
		fields.setSize(1000, 300);
		fields.setLocation(100, 600);

		selectFieldLabel = new JLabel("Select Field:");
		selectFieldLabel.setBackground(Color.black);
		selectFieldLabel.setFont(largeLabelFont);

		logomotionButton = new JButton(logomotionIcon);
		reboundButton = new JButton(reboundIcon);
		fields.add(logomotionButton);
		fields.add(reboundButton);
		FieldListener selectFieldListener = new FieldListener();
		logomotionButton.addActionListener(selectFieldListener);
		reboundButton.addActionListener(selectFieldListener);

		TitledBorder tb = BorderFactory.createTitledBorder("Rebound Rumble");
		tb.setTitleColor(Color.black);
		tb.setTitleJustification(TitledBorder.LEFT);
		reboundButton.setBorder(tb);

		TitledBorder tb2 = BorderFactory.createTitledBorder("Logomotion");
		tb2.setTitleColor(Color.black);
		tb2.setTitleJustification(TitledBorder.LEFT);
		logomotionButton.setBorder(tb2);

		e1 = GraphicsEnvironment.getLocalGraphicsEnvironment();
		setMaximizedBounds(e1.getMaximumWindowBounds());
		setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
		setUndecorated(true);

		//Creates a Help Panel which will be made visible when the user triggers a Key Event
		help = new HelpFrame();
		setTitle("User Robot Selection");		

		//Creates the overall JPanel that contains other JPanels
		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(850, 350));
		panel.setBackground(color);

		//Your Robot and Image
		yourRobotLabel = new JLabel("Your Robot:");
		yourRobotLabel.setFont(largeLabelFont);
		robotLabel = new JLabel(robotIcon);
		robot = new JPanel();
		robot.add(robotLabel);

		//instructions for sliders
		sliderInstructions = new JLabel("Select Attributes:");
		sliderInstructions.setFont(largeLabelFont);

		//sliders
		delaySlider = new JSlider(JSlider.CENTER, sliderMin, sliderMax, (sliderMin + sliderMax) / 2);
		delaySlider.setBorder(BorderFactory.createTitledBorder("Delay"));
		delaySlider.setMajorTickSpacing(25);
		delaySlider.setMinorTickSpacing(5);
		delaySlider.setPaintTicks(true);
		delaySlider.setPaintLabels(true);
		delaySlider.addChangeListener(new SliderListener());
		delaySlider.setBackground(color);

		speedSlider = new JSlider(JSlider.CENTER, sliderMin, sliderMax, (sliderMin + sliderMax) / 2);
		speedSlider.setBorder(BorderFactory.createTitledBorder("Speed"));
		speedSlider.setMajorTickSpacing(25);
		speedSlider.setMinorTickSpacing(5);
		speedSlider.setPaintTicks(true);
		speedSlider.setPaintLabels(true);
		speedSlider.addChangeListener(new SliderListener());
		speedSlider.setBackground(color);		

		pickupSlider = new JSlider(JSlider.CENTER, sliderMin, sliderMax, (sliderMin + sliderMax) / 2);
		pickupSlider.setBorder(BorderFactory.createTitledBorder("Pickup"));
		pickupSlider.setMajorTickSpacing(25);
		pickupSlider.setMinorTickSpacing(5);
		pickupSlider.setPaintTicks(true);
		pickupSlider.setPaintLabels(true);
		pickupSlider.addChangeListener(new SliderListener());
		pickupSlider.setBackground(color);

		shootSlider = new JSlider(JSlider.CENTER, sliderMin, sliderMax, (sliderMin + sliderMax) / 2);
		shootSlider.setBorder(BorderFactory.createTitledBorder("Shoot"));
		shootSlider.setMajorTickSpacing(25);
		shootSlider.setMinorTickSpacing(5);
		shootSlider.setPaintTicks(true);
		shootSlider.setPaintLabels(true);
		shootSlider.addChangeListener(new SliderListener());
		shootSlider.setBackground(color);

		sliders.setBorder(BorderFactory.createLineBorder(Color.black));

		sliders.add(shootSlider);	
		sliders.add(pickupSlider);	
		sliders.add(delaySlider);	
		sliders.add(speedSlider);	
		sliders.setBackground(color);

		//displays the number of points left
		timeDisplay.setText(message);
		timeDisplay.setBorder(BorderFactory.createLineBorder(Color.black));
		timeDisplay.setEditable(false);
		timeDisplay.setFont(new Font("Cambria", Font.BOLD, 25));

		//Start Match Button
		confirmSelection = new JButton("Start Match");
		confirmSelection.setFont(largeLabelFont);
		confirmSelection.addActionListener(new ConfirmListener());

		//top panel: userRobot and instructions
		userRobotPanel = new JPanel();
		userRobotPanel.setBackground(backgroundColor);
		SpringLayout userRobotLayout = new SpringLayout();
		userRobotPanel.setLayout(userRobotLayout);
		userRobotLayout.putConstraint(SpringLayout.WEST, yourRobotLabel, 435, SpringLayout.WEST, userRobotPanel);
		userRobotLayout.putConstraint(SpringLayout.NORTH, yourRobotLabel, 60, SpringLayout.NORTH, userRobotPanel);
		userRobotLayout.putConstraint(SpringLayout.NORTH, robot, 35, SpringLayout.NORTH, userRobotPanel);
		userRobotLayout.putConstraint(SpringLayout.WEST, robot, 20, SpringLayout.EAST, yourRobotLabel);
		userRobotLayout.putConstraint(SpringLayout.WEST, keyInstructionPanel, 255, SpringLayout.EAST, robot);
		userRobotPanel.add(yourRobotLabel);
		userRobotPanel.add(robot);
		userRobotPanel.add(keyInstructionPanel);

		//2nd panel: attribute selection
		selectAttributesPanel = new JPanel();
		selectAttributesPanel.setBackground(backgroundColor);
		SpringLayout selectionLayout = new SpringLayout();
		selectAttributesPanel.setLayout(selectionLayout);
		selectionLayout.putConstraint(SpringLayout.WEST, sliderInstructions, 55, SpringLayout.WEST, selectAttributesPanel);
		selectionLayout.putConstraint(SpringLayout.WEST, sliders, 20, SpringLayout.EAST, sliderInstructions);
		selectionLayout.putConstraint(SpringLayout.NORTH, sliders, 20, SpringLayout.NORTH, selectAttributesPanel);
		selectionLayout.putConstraint(SpringLayout.NORTH, sliderInstructions, 35, SpringLayout.NORTH, selectAttributesPanel);
		selectionLayout.putConstraint(SpringLayout.EAST, timeDisplay, 750, SpringLayout.WEST, selectAttributesPanel);
		selectionLayout.putConstraint(SpringLayout.NORTH, timeDisplay, 30, SpringLayout.SOUTH, sliders);
		selectAttributesPanel.add(sliderInstructions);
		selectAttributesPanel.add(sliders);
		selectAttributesPanel.add(timeDisplay);

		//3rd panel: select Field
		selectFieldPanel = new JPanel();
		selectFieldPanel.setBackground(backgroundColor);
		SpringLayout fieldLayout = new SpringLayout();
		selectFieldPanel.setLayout(fieldLayout);
		fieldLayout.putConstraint(SpringLayout.WEST, selectFieldLabel, 200, SpringLayout.WEST, selectFieldPanel);
		fieldLayout.putConstraint(SpringLayout.NORTH, selectFieldLabel, 60, SpringLayout.NORTH, selectFieldPanel);
		fieldLayout.putConstraint(SpringLayout.NORTH, reboundButton, 25, SpringLayout.NORTH, selectFieldPanel);
		fieldLayout.putConstraint(SpringLayout.NORTH, logomotionButton, 25, SpringLayout.NORTH, selectFieldPanel);
		fieldLayout.putConstraint(SpringLayout.WEST, reboundButton, 20, SpringLayout.EAST, selectFieldLabel);
		fieldLayout.putConstraint(SpringLayout.WEST, logomotionButton, 60, SpringLayout.EAST, reboundButton);
		selectFieldPanel.add(selectFieldLabel);
		selectFieldPanel.add(reboundButton);
		selectFieldPanel.add(logomotionButton);

		//4th panel: start match
		startMatchPanel = new JPanel();
		startMatchPanel.setBackground(backgroundColor);
		SpringLayout startLayout = new SpringLayout();
		startMatchPanel.setLayout(startLayout);
		startLayout.putConstraint(SpringLayout.NORTH, confirmSelection, 40, SpringLayout.NORTH, startMatchPanel);
		startLayout.putConstraint(SpringLayout.WEST, confirmSelection, 520, SpringLayout.WEST, startMatchPanel);
		startMatchPanel.add(confirmSelection);

		//set layout and add everything in order
		panel.setLayout(new GridLayout(4, 1));

		panel.add(userRobotPanel);
		panel.add(selectAttributesPanel);
		panel.add(selectFieldPanel);
		panel.add(startMatchPanel);

		panel.setFocusable(true);

		//key listener
		HelpMenuListener helpListener = new HelpMenuListener();
		panel.addKeyListener(helpListener);		
		delaySlider.addKeyListener(helpListener);
		speedSlider.addKeyListener(helpListener);
		pickupSlider.addKeyListener(helpListener);
		shootSlider.addKeyListener(helpListener);
		logomotionButton.addKeyListener(helpListener);
		reboundButton.addKeyListener(helpListener);

		add(panel);
		pack();
		update();
	}

	//Checks to see if current user slider values exceed the legal maximum for a robot
	//Also, changes the color of the panel the sliders are displayed in
	public void update() {
		currentSum = tempDelay + tempSpeed + tempPickup + tempShoot;
		remainingPoints = Integer.toString(maxSum - currentSum);
		message = "Points left: " + remainingPoints;

		if(tempSpeed <= 55)
			redValue = tempSpeed + 200;
		if(tempPickup <= 55)
			blueValue = tempPickup + 200;
		if(tempShoot <= 55)
			greenValue = tempShoot + 200;

		color = new Color(255, 255, 255);

		if (currentSum > maxSum) {
			timeDisplay.setText("Too many points!");
			confirmSelection.setVisible(false);
			color = new Color(255, 0, 0);
		}

		else {
			timeDisplay.setText(message);
			confirmSelection.setVisible(true);

		}

		shootSlider.setBackground(color);
		speedSlider.setBackground(color);
		delaySlider.setBackground(color);
		pickupSlider.setBackground(color);
		sliders.setBackground(color);
		bottom.setBackground(color);
		setBackground(color);
		timeDisplay.setBackground(color);

	}

	private class SliderListener implements ChangeListener {

		public void stateChanged(ChangeEvent event) {

			if (event.getSource() == delaySlider) {
				if (!delaySlider.getValueIsAdjusting()) {
					tempDelay = delaySlider.getValue();
				}
			}

			if (event.getSource() == speedSlider) {
				if (!delaySlider.getValueIsAdjusting()) {
					tempSpeed = speedSlider.getValue();
				}
			}

			if (event.getSource() == pickupSlider) {
				if (!delaySlider.getValueIsAdjusting()) {
					tempPickup = pickupSlider.getValue();
				}
			}

			if (event.getSource() == shootSlider) {
				if (!delaySlider.getValueIsAdjusting()) {
					tempShoot = shootSlider.getValue();
				}
			}
			update();
		}
	}

	private class ConfirmListener implements ActionListener {
		//Generates the necessary piece list
		//Also, frames are generated containing the field and control panel
		public void actionPerformed(ActionEvent arg0) {
			if(RoboticsProjectPanel.field == null){
				JOptionPane.showMessageDialog(new JFrame(), "Please select a field type!");
			}
			else{
				GamePiece.generateGamePieceList(RoboticsProjectPanel.field.getFieldType(), RoboticsProjectPanel.gamePieceList);
				setVisible(false);		

				createRobots();

				JFrame frame = new JFrame ("Field");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				JPanel z = new JPanel();


				RoboticsProjectPanel panel = new RoboticsProjectPanel();

				z.add(panel);
				z.setBackground(Color.BLACK);
				frame.getContentPane().add(z);
				frame.pack();
				frame.setVisible(true);


				JFrame frame2 = new JFrame ("Control Panel");
				frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				ControlPanel panel2 = new ControlPanel();
				frame2.getContentPane().add(panel2);
				frame2.pack();
				frame2.setVisible(true);
				frame2.setLocation(new Point(0, 660));
			}
		}

		private void createRobots() {
			/*
			 *Creates the 6 robots and puts them into the static RobotPanel
			 *The first one is user generated
			 *The next 5 are randomly generated
			 */

			RoboticsProjectPanel.robotList[0][0] = new Robot(Robot.Alliance.blue, 1, new Point(900, 200), tempDelay, tempSpeed, tempPickup, tempShoot, Robot.State.neutral);
			RoboticsProjectPanel.robotList[0][1] = generateRobot(maxSum);
			RoboticsProjectPanel.robotList[0][2] = generateRobot(maxSum);
			RoboticsProjectPanel.robotList[1][0] = generateRobot(maxSum);
			RoboticsProjectPanel.robotList[1][1] = generateRobot(maxSum);
			RoboticsProjectPanel.robotList[1][2] = generateRobot(maxSum);

			RoboticsProjectPanel.robotList[0][1].setAlliance(Robot.Alliance.blue);
			RoboticsProjectPanel.robotList[0][2].setAlliance(Robot.Alliance.blue); 
			RoboticsProjectPanel.robotList[1][0].setAlliance(Robot.Alliance.red); 
			RoboticsProjectPanel.robotList[1][1].setAlliance(Robot.Alliance.red); 
			RoboticsProjectPanel.robotList[1][2].setAlliance(Robot.Alliance.red); 

			RoboticsProjectPanel.robotList[0][1].setIdentifier(2);
			RoboticsProjectPanel.robotList[0][2].setIdentifier(3);
			RoboticsProjectPanel.robotList[1][0].setIdentifier(1);
			RoboticsProjectPanel.robotList[1][1].setIdentifier(2);
			RoboticsProjectPanel.robotList[1][2].setIdentifier(3);

			RoboticsProjectPanel.robotList[0][1].setPosition(new Point(900 , 300));
			RoboticsProjectPanel.robotList[0][2].setPosition(new Point(900 , 400));
			RoboticsProjectPanel.robotList[1][0].setPosition(new Point(300 , 200));
			RoboticsProjectPanel.robotList[1][1].setPosition(new Point(300 , 300));
			RoboticsProjectPanel.robotList[1][2].setPosition(new Point(300 , 400));

			//Creates the threads for each of the created robots
			for(int j = 0; j < 3; j++){
				RoboticsProjectPanel.robotList[0][j].createThread();
				RoboticsProjectPanel.robotList[1][j].createThread();
			}

			//Adds null zones, which are replaced by the updated zones based on locations of robots
			for(int i=0; i<6; i++){
				RoboticsProjectPanel.field.addZone(null);
			}
			RoboticsProjectPanel.field.updateBoundaries(RoboticsProjectPanel.robotList);
		}
	}

	//WARNING This method does not set the position, alliance, or identifier of the robot
	public static Robot generateRobot(int maxSum) {
		int sum = 0, temp, temp2, temp3, temp4;
		Robot robot = new Robot();
		robot.setState(Robot.State.neutral);

		temp = random.nextInt(99) + 1;
		sum += temp;

		temp2 = random.nextInt(99) + 1;
		sum += temp2;

		temp3 = random.nextInt(99) + 1;
		sum += temp3;

		temp4 = random.nextInt(99) + 1;
		sum += temp4;

		double ratio = maxSum / sum;

		robot.setDelay((int) (temp*ratio));
		robot.setSpeed(10);
		robot.setPickup((int) (temp3*ratio));
		robot.setShoot((int) (temp4*ratio));

		return robot;
	}

	//KeyListener to quit program or help screen
	private class HelpMenuListener implements KeyListener {

		public void keyPressed(KeyEvent event) {
			if (event.getKeyCode() == KeyEvent.VK_H){
				help.setVisible(true);
			}

			if (event.getKeyCode() == KeyEvent.VK_ESCAPE){
				help.setVisible(false);
			}

			//quit out of entire program
			if(event.getKeyCode() == KeyEvent.VK_Q){
				System.exit(0);
			}
		}

		//Overridden methods
		public void keyReleased(KeyEvent event) {}
		public void keyTyped(KeyEvent event) {}

	}

	//selects which field to play the match on
	public class FieldListener implements ActionListener{

		public void actionPerformed(ActionEvent event) {

			if (event.getSource() == reboundButton) {			
				RoboticsProjectPanel.field = new Field(Field.REBOUND_RUMBLE);

				reboundButton.setIcon(selectedReboundIcon);
				logomotionButton.setIcon(logomotionIcon);
			}

			if (event.getSource() == logomotionButton) {			
				RoboticsProjectPanel.field = new Field(Field.LOGOMOTION);

				logomotionButton.setIcon(selectedLogomotionIcon);
				reboundButton.setIcon(reboundIcon);

			}

		}
	}
}
